<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><title>Spring源码系列-第4章-Bean初始化流程 | 风祈的时光录</title><meta name="keywords" content="Spring，框架，spring源码"><meta name="author" content="youthlql"><meta name="copyright" content="youthlql"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="总结一下Bean的初始化">
<meta property="og:type" content="article">
<meta property="og:title" content="Spring源码系列-第4章-Bean初始化流程">
<meta property="og:url" content="https://imlql.cn/post/49f419ae.html">
<meta property="og:site_name" content="风祈的时光录">
<meta property="og:description" content="总结一下Bean的初始化">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://npm.elemecdn.com/lql_static@latest/logo/spring.png">
<meta property="article:published_time" content="2022-01-27T13:01:02.000Z">
<meta property="article:modified_time" content="2022-07-24T11:22:15.042Z">
<meta property="article:author" content="youthlql">
<meta property="article:tag" content="Spring源码">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://npm.elemecdn.com/lql_static@latest/logo/spring.png"><link rel="shortcut icon" href="https://npm.elemecdn.com/youthlql@1.0.8/blog/favicon.png"><link rel="canonical" href="https://imlql.cn/post/49f419ae"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//hm.baidu.com"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://npm.elemecdn.com/@fortawesome/fontawesome-free@6/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://npm.elemecdn.com/@fancyapps/ui/dist/fancybox.css" media="print" onload="this.media='all'"><script>var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?f693ff99cc7e613b88cf5b729a14b48b";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script><script>const GLOBAL_CONFIG = { 
  root: '/',
  algolia: undefined,
  localSearch: {"path":"search.xml","languages":{"hits_empty":"找不到您查询的内容：${query}"}},
  translate: {"defaultEncoding":2,"translateDelay":0,"msgToTraditionalChinese":"繁","msgToSimplifiedChinese":"簡"},
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '天',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: undefined,
  source: {
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery@2/dist/fjGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery@2/dist/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: true,
  isAnchor: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: 'Spring源码系列-第4章-Bean初始化流程',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2022-07-24 19:22:15'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script><link rel="stylesheet" href="https://npm.elemecdn.com/lql_static@latest/butterfly_static/css/ali_icon.css"><link rel="stylesheet" href="https://npm.elemecdn.com/lql_static@latest/butterfly_static/css/2-24-mogai.css"><meta name="generator" content="Hexo 5.4.0"><link rel="alternate" href="/atom.xml" title="风祈的时光录" type="application/atom+xml">
</head><body><div id="web_bg"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src= "" data-lazy-src="https://npm.elemecdn.com/lql_static@latest/avatar/2.jpg" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="site-data is-center"><div class="data-item"><a href="/archives/"><div class="headline">文章</div><div class="length-num">37</div></a></div><div class="data-item"><a href="/tags/"><div class="headline">标签</div><div class="length-num">21</div></a></div><div class="data-item"><a href="/categories/"><div class="headline">分类</div><div class="length-num">13</div></a></div></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw iconfont icon-shouyex"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw iconfont icon-zuixinwenzhang_huaban"></i><span> 找文章</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/categories/"><i class="fa-fw iconfont icon-fenlei1"></i><span> 分类</span></a></li><li><a class="site-page child" href="/tags/"><i class="fa-fw iconfont icon-biaoqian1"></i><span> 标签</span></a></li><li><a class="site-page child" href="/archives/"><i class="fa-fw iconfont icon-shijianzhou"></i><span> 归档</span></a></li></ul></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('https://npm.elemecdn.com/lql_static@latest/logo/spring.png')"><nav id="nav"><span id="blog_name"><a id="site-name" href="/">风祈的时光录</a></span><div id="menus"><div id="search-button"><a class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw iconfont icon-shouyex"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw iconfont icon-zuixinwenzhang_huaban"></i><span> 找文章</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/categories/"><i class="fa-fw iconfont icon-fenlei1"></i><span> 分类</span></a></li><li><a class="site-page child" href="/tags/"><i class="fa-fw iconfont icon-biaoqian1"></i><span> 标签</span></a></li><li><a class="site-page child" href="/archives/"><i class="fa-fw iconfont icon-shijianzhou"></i><span> 归档</span></a></li></ul></div></div><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">Spring源码系列-第4章-Bean初始化流程</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2022-01-27T13:01:02.000Z" title="发表于 2022-01-27 21:01:02">2022-01-27</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2022-07-24T11:22:15.042Z" title="更新于 2022-07-24 19:22:15">2022-07-24</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/Spring/">Spring</a><i class="fas fa-angle-right post-meta-separator"></i><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/Spring/%E6%BA%90%E7%A0%81V1/">源码V1</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">4k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>20分钟</span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h1 id="第4章-Bean初始化流程"><a href="#第4章-Bean初始化流程" class="headerlink" title="第4章-Bean初始化流程"></a>第4章-Bean初始化流程</h1><h2 id="流程图-bean初始化流程"><a href="#流程图-bean初始化流程" class="headerlink" title="流程图-bean初始化流程"></a>流程图-bean初始化流程</h2><img src= "" data-lazy-src="https://upyunimg.imlql.cn/youthlql@1.0.7/spring-sourcecode-v1/flow_chart/bean%E5%88%9D%E5%A7%8B%E5%8C%96%E6%B5%81%E7%A8%8B.jpg">

<h2 id="AbstractApplicationContext-refresh"><a href="#AbstractApplicationContext-refresh" class="headerlink" title="AbstractApplicationContext#refresh()"></a>AbstractApplicationContext#refresh()</h2><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Override</span>  <span class="comment">//容器刷新的十二大步。模板模式</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">refresh</span><span class="params">()</span> <span class="keyword">throws</span> BeansException, IllegalStateException </span>&#123;</span><br><span class="line">   <span class="keyword">synchronized</span> (<span class="keyword">this</span>.startupShutdownMonitor) &#123;</span><br><span class="line">      StartupStep contextRefresh = <span class="keyword">this</span>.applicationStartup.start(<span class="string">&quot;spring.context.refresh&quot;</span>);</span><br><span class="line"></span><br><span class="line">      <span class="comment">// Prepare this context for refreshing.</span></span><br><span class="line">      prepareRefresh();</span><br><span class="line"></span><br><span class="line">      <span class="comment">// Tell the subclass to refresh the internal bean factory.</span></span><br><span class="line">      <span class="comment">// 工厂创建：BeanFactory第一次开始创建的时候,有xml解析逻辑。</span></span><br><span class="line">      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();</span><br><span class="line"></span><br><span class="line">      <span class="comment">// Prepare the bean factory for use in this context.</span></span><br><span class="line">      prepareBeanFactory(beanFactory);</span><br><span class="line"></span><br><span class="line">      <span class="keyword">try</span> &#123;</span><br><span class="line">         <span class="comment">// Allows post-processing of the bean factory in context subclasses.</span></span><br><span class="line">         postProcessBeanFactory(beanFactory);</span><br><span class="line"></span><br><span class="line">         StartupStep beanPostProcess = <span class="keyword">this</span>.applicationStartup.start(<span class="string">&quot;spring.context.beans.post-process&quot;</span>);</span><br><span class="line">         <span class="comment">//工厂增强：执行所有的BeanFactory后置增强器；利用BeanFactory后置增强器对工厂进行修改或者增强,配置类会在这里进行解析。 Invoke factory processors registered as beans in the context.</span></span><br><span class="line">         invokeBeanFactoryPostProcessors(beanFactory);</span><br><span class="line"></span><br><span class="line">         <span class="comment">//注册所有的Bean的后置处理器 Register bean processors that intercept bean creation.</span></span><br><span class="line">         registerBeanPostProcessors(beanFactory);</span><br><span class="line">         beanPostProcess.end();</span><br><span class="line"></span><br><span class="line">         <span class="comment">// Initialize message source for this context.</span></span><br><span class="line">         initMessageSource();</span><br><span class="line"></span><br><span class="line">         <span class="comment">// Initialize event multicaster for this context.</span></span><br><span class="line">         initApplicationEventMulticaster();</span><br><span class="line"></span><br><span class="line">         <span class="comment">// Initialize other special beans in specific context subclasses.</span></span><br><span class="line">         onRefresh();</span><br><span class="line"></span><br><span class="line">         <span class="comment">//注册监听器，从容器中获取所有的ApplicationListener； Check for listener beans and register them.</span></span><br><span class="line">         registerListeners();</span><br><span class="line"></span><br><span class="line">         <span class="comment">// Instantiate all remaining (non-lazy-init) singletons.</span></span><br><span class="line">         <span class="comment">//bean创建；完成 BeanFactory 初始化。（工厂里面所有的组件都好了）</span></span><br><span class="line">         finishBeanFactoryInitialization(beanFactory);</span><br><span class="line"></span><br><span class="line">         <span class="comment">// Last step: publish corresponding event.</span></span><br><span class="line">         finishRefresh();</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">catch</span> (BeansException ex) &#123;</span><br><span class="line">         <span class="keyword">if</span> (logger.isWarnEnabled()) &#123;</span><br><span class="line">            logger.warn(<span class="string">&quot;Exception encountered during context initialization - &quot;</span> +</span><br><span class="line">                  <span class="string">&quot;cancelling refresh attempt: &quot;</span> + ex);</span><br><span class="line">         &#125;</span><br><span class="line"></span><br><span class="line">         <span class="comment">// Destroy already created singletons to avoid dangling resources.</span></span><br><span class="line">         destroyBeans();</span><br><span class="line"></span><br><span class="line">         <span class="comment">// Reset &#x27;active&#x27; flag.</span></span><br><span class="line">         cancelRefresh(ex);</span><br><span class="line"></span><br><span class="line">         <span class="comment">// Propagate exception to caller.</span></span><br><span class="line">         <span class="keyword">throw</span> ex;</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">finally</span> &#123;</span><br><span class="line">         <span class="comment">// Reset common introspection caches in Spring&#x27;s core, since we</span></span><br><span class="line">         <span class="comment">// might not ever need metadata for singleton beans anymore...</span></span><br><span class="line">         resetCommonCaches();</span><br><span class="line">         contextRefresh.end();</span><br><span class="line">      &#125;</span><br><span class="line">   &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="AbstractApplicationContext-finishBeanFactoryInitialization"><a href="#AbstractApplicationContext-finishBeanFactoryInitialization" class="headerlink" title="AbstractApplicationContext#finishBeanFactoryInitialization()"></a>AbstractApplicationContext#finishBeanFactoryInitialization()</h2><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">finishBeanFactoryInitialization</span><span class="params">(ConfigurableListableBeanFactory beanFactory)</span> </span>&#123;</span><br><span class="line">	<span class="comment">// 给工厂设置好 ConversionService【负责类型转换的组件服务】， Initialize conversion service for this context.</span></span><br><span class="line">	<span class="keyword">if</span> (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &amp;&amp;</span><br><span class="line">			beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) &#123;</span><br><span class="line">		beanFactory.setConversionService(</span><br><span class="line">				beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// 注册一个默认的值解析器（&quot;$&#123;&#125;&quot;）  ；Register a default embedded value resolver if no BeanFactoryPostProcessor</span></span><br><span class="line">	<span class="comment">// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:</span></span><br><span class="line">	<span class="comment">// at this point, primarily for resolution in annotation attribute values.</span></span><br><span class="line">	<span class="keyword">if</span> (!beanFactory.hasEmbeddedValueResolver()) &#123;</span><br><span class="line">		beanFactory.addEmbeddedValueResolver(strVal -&gt; getEnvironment().resolvePlaceholders(strVal));</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// LoadTimeWeaverAware；aspectj：加载时织入功能【aop】。 Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.</span></span><br><span class="line">	String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, <span class="keyword">false</span>, <span class="keyword">false</span>);</span><br><span class="line">	<span class="keyword">for</span> (String weaverAwareName : weaverAwareNames) &#123;</span><br><span class="line">		getBean(weaverAwareName); <span class="comment">//从容器中获取组件，有则直接获取，没则进行创建</span></span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Stop using the temporary ClassLoader for type matching.</span></span><br><span class="line">	beanFactory.setTempClassLoader(<span class="keyword">null</span>);</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Allow for caching all bean definition metadata, not expecting further changes.</span></span><br><span class="line">	beanFactory.freezeConfiguration();</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Instantiate all remaining (non-lazy-init) singletons.</span></span><br><span class="line">	<span class="comment">//初始化所有的非懒加载的单实例Bean</span></span><br><span class="line">	beanFactory.preInstantiateSingletons();  </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>





<h2 id="DefaultListableBeanFactory-preInstantiateSingletons"><a href="#DefaultListableBeanFactory-preInstantiateSingletons" class="headerlink" title="DefaultListableBeanFactory#preInstantiateSingletons()"></a>DefaultListableBeanFactory#preInstantiateSingletons()</h2><figure class="highlight java"><table><tr><td class="code"><pre><span class="line">   </span><br><span class="line">String FACTORY_BEAN_PREFIX = <span class="string">&quot;&amp;&quot;</span>;	</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">preInstantiateSingletons</span><span class="params">()</span> <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line">      <span class="keyword">if</span> (logger.isTraceEnabled()) &#123;</span><br><span class="line">         logger.trace(<span class="string">&quot;Pre-instantiating singletons in &quot;</span> + <span class="keyword">this</span>);</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      <span class="comment">// Iterate over a copy to allow for init methods which in turn register new bean definitions.</span></span><br><span class="line">      <span class="comment">// While this may not be part of the regular factory bootstrap, it does otherwise work fine.</span></span><br><span class="line">      List&lt;String&gt; beanNames = <span class="keyword">new</span> ArrayList&lt;&gt;(<span class="keyword">this</span>.beanDefinitionNames);</span><br><span class="line"></span><br><span class="line">      <span class="comment">// 创建出所有的单实例Bean；Trigger initialization of all non-lazy singleton beans...</span></span><br><span class="line">      <span class="keyword">for</span> (String beanName : beanNames) &#123;</span><br><span class="line">         RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); <span class="comment">//开始解析文件的时候每一个bean标签被解析封装成一个BeanDefinition</span></span><br><span class="line">         <span class="keyword">if</span> (!bd.isAbstract() &amp;&amp; bd.isSingleton() &amp;&amp; !bd.isLazyInit()) &#123;</span><br><span class="line">            <span class="keyword">if</span> (isFactoryBean(beanName)) &#123; <span class="comment">//如果是FactoryBean则执行下面逻辑</span></span><br><span class="line">               Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); <span class="comment">//得到HelloFactory</span></span><br><span class="line">               <span class="keyword">if</span> (bean <span class="keyword">instanceof</span> FactoryBean) &#123;</span><br><span class="line">                  FactoryBean&lt;?&gt; factory = (FactoryBean&lt;?&gt;) bean;</span><br><span class="line">                  <span class="keyword">boolean</span> isEagerInit;</span><br><span class="line">                  <span class="keyword">if</span> (System.getSecurityManager() != <span class="keyword">null</span> &amp;&amp; factory <span class="keyword">instanceof</span> SmartFactoryBean) &#123;</span><br><span class="line">                     isEagerInit = AccessController.doPrivileged(</span><br><span class="line">                           (PrivilegedAction&lt;Boolean&gt;) ((SmartFactoryBean&lt;?&gt;) factory)::isEagerInit,</span><br><span class="line">                           getAccessControlContext());</span><br><span class="line">                  &#125;</span><br><span class="line">                  <span class="keyword">else</span> &#123;</span><br><span class="line">                     isEagerInit = (factory <span class="keyword">instanceof</span> SmartFactoryBean &amp;&amp;</span><br><span class="line">                           ((SmartFactoryBean&lt;?&gt;) factory).isEagerInit());</span><br><span class="line">                  &#125;</span><br><span class="line">                  <span class="keyword">if</span> (isEagerInit) &#123;</span><br><span class="line">                     getBean(beanName);</span><br><span class="line">                  &#125;</span><br><span class="line">               &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> &#123; <span class="comment">//不是FactoryBean则执行这个,普通的单实例非懒加载bean的创建</span></span><br><span class="line">               getBean(beanName); <span class="comment">//</span></span><br><span class="line">            &#125;</span><br><span class="line">         &#125;</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      <span class="comment">// 触发 post-initialization 逻辑；  Trigger post-initialization callback for all applicable beans...</span></span><br><span class="line">      <span class="keyword">for</span> (String beanName : beanNames) &#123;</span><br><span class="line">         Object singletonInstance = getSingleton(beanName);</span><br><span class="line">         <span class="keyword">if</span> (singletonInstance <span class="keyword">instanceof</span> SmartInitializingSingleton) &#123;</span><br><span class="line">            StartupStep smartInitialize = <span class="keyword">this</span>.getApplicationStartup().start(<span class="string">&quot;spring.beans.smart-initialize&quot;</span>)</span><br><span class="line">                  .tag(<span class="string">&quot;beanName&quot;</span>, beanName);</span><br><span class="line">            SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;</span><br><span class="line">            <span class="keyword">if</span> (System.getSecurityManager() != <span class="keyword">null</span>) &#123;</span><br><span class="line">               AccessController.doPrivileged((PrivilegedAction&lt;Object&gt;) () -&gt; &#123;</span><br><span class="line">                  smartSingleton.afterSingletonsInstantiated();</span><br><span class="line">                  <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">               &#125;, getAccessControlContext());</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> &#123;</span><br><span class="line">               smartSingleton.afterSingletonsInstantiated();</span><br><span class="line">            &#125;</span><br><span class="line">            smartInitialize.end();</span><br><span class="line">         &#125;</span><br><span class="line">      &#125;</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure>



<h2 id="工厂Bean的初始化方式"><a href="#工厂Bean的初始化方式" class="headerlink" title="工厂Bean的初始化方式"></a>工厂Bean的初始化方式</h2><img src= "" data-lazy-src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_04/image-20210930171319531.png"/>





<h3 id="AbstractBeanFactory-isFactoryBean"><a href="#AbstractBeanFactory-isFactoryBean" class="headerlink" title="AbstractBeanFactory#isFactoryBean()"></a>AbstractBeanFactory#isFactoryBean()</h3><figure class="highlight java"><table><tr><td class="code"><pre><span class="line">   <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isFactoryBean</span><span class="params">(String name)</span> <span class="keyword">throws</span> NoSuchBeanDefinitionException </span>&#123;</span><br><span class="line">      String beanName = transformedBeanName(name);</span><br><span class="line">      Object beanInstance = getSingleton(beanName, <span class="keyword">false</span>);</span><br><span class="line">      <span class="keyword">if</span> (beanInstance != <span class="keyword">null</span>) &#123;</span><br><span class="line">         <span class="keyword">return</span> (beanInstance <span class="keyword">instanceof</span> FactoryBean);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="comment">// No singleton instance found -&gt; check bean definition.</span></span><br><span class="line">      <span class="keyword">if</span> (!containsBeanDefinition(beanName) &amp;&amp; getParentBeanFactory() <span class="keyword">instanceof</span> ConfigurableBeanFactory) &#123;</span><br><span class="line">         <span class="comment">// No bean definition found in this factory -&gt; delegate to parent.</span></span><br><span class="line">         <span class="keyword">return</span> ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">return</span> isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));</span><br><span class="line">   &#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">boolean</span> <span class="title">isFactoryBean</span><span class="params">(String beanName, RootBeanDefinition mbd)</span> </span>&#123;</span><br><span class="line">      Boolean result = mbd.isFactoryBean;</span><br><span class="line">      <span class="keyword">if</span> (result == <span class="keyword">null</span>) &#123;</span><br><span class="line">         Class&lt;?&gt; beanType = predictBeanType(beanName, mbd, FactoryBean.class);</span><br><span class="line">         result = (beanType != <span class="keyword">null</span> &amp;&amp; FactoryBean.class.isAssignableFrom(beanType));</span><br><span class="line">         mbd.isFactoryBean = result;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">return</span> result;</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure>



<p>无论是不是工厂Bean，最后调用的都是<code>AbstractBeanFactory#getBean(String name)</code></p>
<h3 id="测试类"><a href="#测试类" class="headerlink" title="测试类"></a>测试类</h3><p>由于工厂Bean只有在你getBean获取的时候，它才会创建，所以我们必须用这些测试类测试一下。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">AnnotationMainTest</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">   <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">      ApplicationContext applicationContext =</span><br><span class="line">            <span class="keyword">new</span> AnnotationConfigApplicationContext(MainConfig.class);</span><br><span class="line">      Hello bean = applicationContext.getBean(Hello.class);</span><br><span class="line">      System.out.println(bean); </span><br><span class="line"></span><br><span class="line">   &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>MainConfig</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@ComponentScan(&quot;cn.imlql.spring&quot;)</span></span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MainConfig</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">   <span class="function"><span class="keyword">public</span> <span class="title">MainConfig</span><span class="params">()</span></span>&#123;</span><br><span class="line">      System.out.println(<span class="string">&quot;MainConfig...创建了....&quot;</span>);</span><br><span class="line">   &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<p><strong>HelloFactory</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Component</span>  <span class="comment">//也可以实现 SmartFactoryBean。指定提前加载</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">HelloFactory</span> <span class="keyword">implements</span> <span class="title">FactoryBean</span>&lt;<span class="title">Hello</span>&gt; </span>&#123;</span><br><span class="line"></span><br><span class="line">   <span class="meta">@Override</span></span><br><span class="line">   <span class="function"><span class="keyword">public</span> Hello <span class="title">getObject</span><span class="params">()</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line">      <span class="keyword">return</span> <span class="keyword">new</span> Hello(); <span class="comment">//这是最终获取到的对象    pos_1</span></span><br><span class="line">   &#125;</span><br><span class="line"></span><br><span class="line">   <span class="meta">@Override</span></span><br><span class="line">   <span class="keyword">public</span> Class&lt;?&gt; getObjectType() &#123;</span><br><span class="line">      <span class="keyword">return</span> Hello.class;</span><br><span class="line">   &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>pos_1位置打个断点。</p>
<p><strong>Hello</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Hello</span> </span>&#123;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h3 id="Debug调用栈"><a href="#Debug调用栈" class="headerlink" title="Debug调用栈"></a>Debug调用栈</h3><p>从这里开始看调用链</p>
<img src= "" data-lazy-src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_04/image-20210930175345542.png"/>





<img src= "" data-lazy-src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_04/image-20210930175539928.png"/>





<h3 id="DefaultListableBeanFactory-resolveBean"><a href="#DefaultListableBeanFactory-resolveBean" class="headerlink" title="DefaultListableBeanFactory#resolveBean()"></a>DefaultListableBeanFactory#resolveBean()</h3><figure class="highlight java"><table><tr><td class="code"><pre><span class="line">   <span class="meta">@Nullable</span></span><br><span class="line">   <span class="keyword">private</span> &lt;T&gt; <span class="function">T <span class="title">resolveBean</span><span class="params">(ResolvableType requiredType, <span class="meta">@Nullable</span> Object[] args, <span class="keyword">boolean</span> nonUniqueAsNull)</span> </span>&#123;</span><br><span class="line">      NamedBeanHolder&lt;T&gt; namedBean = resolveNamedBean(requiredType, args, nonUniqueAsNull);</span><br><span class="line">      <span class="keyword">if</span> (namedBean != <span class="keyword">null</span>) &#123;</span><br><span class="line">         <span class="keyword">return</span> namedBean.getBeanInstance();</span><br><span class="line">      &#125;</span><br><span class="line">      BeanFactory parent = getParentBeanFactory();</span><br><span class="line">      <span class="keyword">if</span> (parent <span class="keyword">instanceof</span> DefaultListableBeanFactory) &#123;</span><br><span class="line">         <span class="keyword">return</span> ((DefaultListableBeanFactory) parent).resolveBean(requiredType, args, nonUniqueAsNull);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">else</span> <span class="keyword">if</span> (parent != <span class="keyword">null</span>) &#123;</span><br><span class="line">         ObjectProvider&lt;T&gt; parentProvider = parent.getBeanProvider(requiredType);</span><br><span class="line">         <span class="keyword">if</span> (args != <span class="keyword">null</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> parentProvider.getObject(args);</span><br><span class="line">         &#125;</span><br><span class="line">         <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> (nonUniqueAsNull ? parentProvider.getIfUnique() : parentProvider.getIfAvailable());</span><br><span class="line">         &#125;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">   &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> &lt;T&gt; <span class="function">NamedBeanHolder&lt;T&gt; <span class="title">resolveNamedBean</span><span class="params">(</span></span></span><br><span class="line"><span class="function"><span class="params">		ResolvableType requiredType, <span class="meta">@Nullable</span> Object[] args, <span class="keyword">boolean</span> nonUniqueAsNull)</span> <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line"></span><br><span class="line">	Assert.notNull(requiredType, <span class="string">&quot;Required type must not be null&quot;</span>);</span><br><span class="line">	String[] candidateNames = getBeanNamesForType(requiredType); <span class="comment">//按照类型获取组件</span></span><br><span class="line"></span><br><span class="line">	<span class="comment">// ... </span></span><br><span class="line"></span><br><span class="line">	<span class="keyword">if</span> (candidateNames.length == <span class="number">1</span>) &#123;</span><br><span class="line">		<span class="keyword">return</span> resolveNamedBean(candidateNames[<span class="number">0</span>], requiredType, args);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">// ...</span></span><br><span class="line">	<span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h3 id="DefaultListableBeanFactory-doGetBeanNamesForType"><a href="#DefaultListableBeanFactory-doGetBeanNamesForType" class="headerlink" title="DefaultListableBeanFactory#doGetBeanNamesForType()"></a>DefaultListableBeanFactory#doGetBeanNamesForType()</h3><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//获取某一个组件在容器中的名字。   工厂Bean的主要逻辑还是走到这里，这里我们之前讲过</span></span><br><span class="line"><span class="keyword">private</span> String[] doGetBeanNamesForType(ResolvableType type, <span class="keyword">boolean</span> includeNonSingletons, <span class="keyword">boolean</span> allowEagerInit) &#123;</span><br><span class="line">	List&lt;String&gt; result = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Check all bean definitions. 因为Spring没有直接保存class--bean名字的对应信息，只能遍历所有的beanname，拿出他们beanname的定义信息，再看是否我指定的类型。</span></span><br><span class="line">	<span class="keyword">for</span> (String beanName : <span class="keyword">this</span>.beanDefinitionNames) &#123;</span><br><span class="line">		<span class="comment">// Only consider bean as eligible if the bean name is not defined as alias for some other bean.</span></span><br><span class="line">		<span class="keyword">if</span> (!isAlias(beanName)) &#123; <span class="comment">//判断是否别名</span></span><br><span class="line">			<span class="keyword">try</span> &#123;</span><br><span class="line">				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);</span><br><span class="line">				<span class="comment">// Only check bean definition if it is complete.</span></span><br><span class="line">				<span class="keyword">if</span> (!mbd.isAbstract() &amp;&amp; (allowEagerInit ||</span><br><span class="line">						(mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &amp;&amp;</span><br><span class="line">								!requiresEagerInitForType(mbd.getFactoryBeanName()))) &#123;</span><br><span class="line">					<span class="keyword">boolean</span> isFactoryBean = isFactoryBean(beanName, mbd); <span class="comment">//是否FactoryBean</span></span><br><span class="line">					BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();</span><br><span class="line">					<span class="keyword">boolean</span> matchFound = <span class="keyword">false</span>;</span><br><span class="line">					<span class="keyword">boolean</span> allowFactoryBeanInit = (allowEagerInit || containsSingleton(beanName));</span><br><span class="line">					<span class="keyword">boolean</span> isNonLazyDecorated = (dbd != <span class="keyword">null</span> &amp;&amp; !mbd.isLazyInit());</span><br><span class="line">					<span class="keyword">if</span> (!isFactoryBean) &#123;</span><br><span class="line">						<span class="keyword">if</span> (includeNonSingletons || isSingleton(beanName, mbd, dbd)) &#123;</span><br><span class="line">							matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit); <span class="comment">//是否类型匹配？</span></span><br><span class="line">						&#125;</span><br><span class="line">					&#125;</span><br><span class="line">					<span class="keyword">else</span> &#123;</span><br><span class="line">						<span class="keyword">if</span> (includeNonSingletons || isNonLazyDecorated ||</span><br><span class="line">								(allowFactoryBeanInit &amp;&amp; isSingleton(beanName, mbd, dbd))) &#123;</span><br><span class="line">							matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);</span><br><span class="line">						&#125;</span><br><span class="line">						<span class="keyword">if</span> (!matchFound) &#123;</span><br><span class="line">							<span class="comment">// In case of FactoryBean, try to match FactoryBean instance itself next.</span></span><br><span class="line">							beanName = FACTORY_BEAN_PREFIX + beanName;</span><br><span class="line">							matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);</span><br><span class="line">						&#125;</span><br><span class="line">					&#125;</span><br><span class="line">					<span class="keyword">if</span> (matchFound) &#123;</span><br><span class="line">						result.add(beanName);</span><br><span class="line">					&#125;</span><br><span class="line">				&#125;</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">catch</span> (CannotLoadBeanClassException | BeanDefinitionStoreException ex) &#123;</span><br><span class="line">				<span class="keyword">if</span> (allowEagerInit) &#123;</span><br><span class="line">					<span class="keyword">throw</span> ex;</span><br><span class="line">				&#125;</span><br><span class="line">				<span class="comment">// Probably a placeholder: let&#x27;s ignore it for type matching purposes.</span></span><br><span class="line">				LogMessage message = (ex <span class="keyword">instanceof</span> CannotLoadBeanClassException ?</span><br><span class="line">						LogMessage.format(<span class="string">&quot;Ignoring bean class loading failure for bean &#x27;%s&#x27;&quot;</span>, beanName) :</span><br><span class="line">						LogMessage.format(<span class="string">&quot;Ignoring unresolvable metadata in bean definition &#x27;%s&#x27;&quot;</span>, beanName));</span><br><span class="line">				logger.trace(message, ex);</span><br><span class="line">				<span class="comment">// Register exception, in case the bean was accidentally unresolvable.</span></span><br><span class="line">				onSuppressedException(ex);</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">catch</span> (NoSuchBeanDefinitionException ex) &#123;</span><br><span class="line">				<span class="comment">// Bean definition got removed while we were iterating -&gt; ignore.</span></span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">// Check manually registered singletons too.</span></span><br><span class="line">	<span class="keyword">for</span> (String beanName : <span class="keyword">this</span>.manualSingletonNames) &#123;</span><br><span class="line">		<span class="keyword">try</span> &#123;</span><br><span class="line">			<span class="comment">// In case of FactoryBean, match object created by FactoryBean.</span></span><br><span class="line">			<span class="keyword">if</span> (isFactoryBean(beanName)) &#123;</span><br><span class="line">				<span class="keyword">if</span> ((includeNonSingletons || isSingleton(beanName)) &amp;&amp; isTypeMatch(beanName, type)) &#123;</span><br><span class="line">					result.add(beanName);</span><br><span class="line">					<span class="comment">// Match found for this bean: do not match FactoryBean itself anymore.</span></span><br><span class="line">					<span class="keyword">continue</span>;</span><br><span class="line">				&#125;</span><br><span class="line">				<span class="comment">// In case of FactoryBean, try to match FactoryBean itself next.</span></span><br><span class="line">				beanName = FACTORY_BEAN_PREFIX + beanName;<span class="comment">//注意这里的工厂Bean前缀</span></span><br><span class="line">			&#125;</span><br><span class="line">			<span class="comment">// Match raw bean instance (might be raw FactoryBean).</span></span><br><span class="line">			<span class="keyword">if</span> (isTypeMatch(beanName, type)) &#123;</span><br><span class="line">				result.add(beanName);</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">catch</span> (NoSuchBeanDefinitionException ex) &#123;</span><br><span class="line">			<span class="comment">// Shouldn&#x27;t happen - probably a result of circular reference resolution...</span></span><br><span class="line">			logger.trace(LogMessage.format(</span><br><span class="line">					<span class="string">&quot;Failed to check manually registered singleton with name &#x27;%s&#x27;&quot;</span>, beanName), ex);</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="keyword">return</span> StringUtils.toStringArray(result);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="BeanFactory"><a href="#BeanFactory" class="headerlink" title="BeanFactory"></a>BeanFactory</h3><figure class="highlight java"><table><tr><td class="code"><pre><span class="line">String FACTORY_BEAN_PREFIX = <span class="string">&quot;&amp;&quot;</span>;</span><br></pre></td></tr></table></figure>

<ol>
<li>工厂Bean在Spring容器中一开始保存的是工厂本身，在这里就是HelloFactory</li>
<li>第一次获取Hello组件的时候。doGetBeanNamesForType循环所有组件，找有没有一个beanName是Hello的组件</li>
<li>它在找的途中发现了HelloFactory这个工厂bean，于是就调用<code>HelloFactory#getObject()</code>，创建Hello这个bean</li>
</ol>
<p>最后返回</p>
<img src= "" data-lazy-src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_04/image-20210930180811270.png"/>





<img src= "" data-lazy-src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_04/image-20210930181219048.png"/>





<h2 id="Bean创建的前期"><a href="#Bean创建的前期" class="headerlink" title="Bean创建的前期"></a>Bean创建的前期</h2><h3 id="测试类-1"><a href="#测试类-1" class="headerlink" title="测试类"></a>测试类</h3><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Cat</span> <span class="keyword">implements</span> <span class="title">InitializingBean</span>, <span class="title">SmartInitializingSingleton</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">   <span class="function"><span class="keyword">public</span> <span class="title">Cat</span><span class="params">()</span></span>&#123;</span><br><span class="line">      System.out.println(<span class="string">&quot;cat被创建了...&quot;</span>);</span><br><span class="line">   &#125;</span><br><span class="line"></span><br><span class="line">   <span class="keyword">private</span> String name;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">   <span class="meta">@Value(&quot;$&#123;JAVA_HOME&#125;&quot;)</span> <span class="comment">//自动赋值功能</span></span><br><span class="line">   <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setName</span><span class="params">(String name)</span> </span>&#123;</span><br><span class="line">      System.out.println(<span class="string">&quot;cat....setName正在赋值调用....&quot;</span>);</span><br><span class="line">      <span class="keyword">this</span>.name = name;</span><br><span class="line">   &#125;</span><br><span class="line">   <span class="comment">//注解怎么定义这个是初始化方法？</span></span><br><span class="line">   <span class="function"><span class="keyword">public</span> String <span class="title">getName</span><span class="params">()</span> </span>&#123;</span><br><span class="line">      <span class="keyword">return</span> name;</span><br><span class="line">   &#125;</span><br><span class="line"></span><br><span class="line">   <span class="meta">@Override</span></span><br><span class="line">   <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">afterPropertiesSet</span><span class="params">()</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line">      System.out.println(<span class="string">&quot;CatInitializingBean..afterPropertiesSet...&quot;</span>);</span><br><span class="line">   &#125;</span><br><span class="line"></span><br><span class="line">   <span class="meta">@Override</span></span><br><span class="line">   <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">afterSingletonsInstantiated</span><span class="params">()</span> </span>&#123;</span><br><span class="line">      System.out.println(<span class="string">&quot;所有组件都创建完成以后，再来执行这个方法.....&quot;</span>);</span><br><span class="line">   &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>测试类基本都是大同小异的，这里不再给出全部的测试类，只给出这一小节用得到的。</p>
</blockquote>
<p>我们以创建Cat这个Bean为例子来讲解。</p>
<h3 id="Debug调用栈-1"><a href="#Debug调用栈-1" class="headerlink" title="Debug调用栈"></a>Debug调用栈</h3><img src= "" data-lazy-src="https://upyunimg.imlql.cn/youthlql@1.0.6/spring-sourcecode-v1/chapter_04/image-20211008174534713.png"/>





<h3 id="AbstractBeanFactory-doGetBean"><a href="#AbstractBeanFactory-doGetBean" class="headerlink" title="AbstractBeanFactory#doGetBean()"></a>AbstractBeanFactory#doGetBean()</h3><figure class="highlight java"><table><tr><td class="code"><pre><span class="line">   <span class="keyword">protected</span> &lt;T&gt; <span class="function">T <span class="title">doGetBean</span><span class="params">(</span></span></span><br><span class="line"><span class="function"><span class="params">         String name, <span class="meta">@Nullable</span> Class&lt;T&gt; requiredType, <span class="meta">@Nullable</span> Object[] args, <span class="keyword">boolean</span> typeCheckOnly)</span></span></span><br><span class="line"><span class="function">         <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line"></span><br><span class="line">      String beanName = transformedBeanName(name); <span class="comment">//转换Bean名字</span></span><br><span class="line">      Object beanInstance;</span><br><span class="line"></span><br><span class="line">      <span class="comment">// 先检查单实例bean的缓存 Eagerly check singleton cache for manually registered singletons.</span></span><br><span class="line">      Object sharedInstance = getSingleton(beanName); <span class="comment">//检查缓存中有没有，如果是第一次获取肯定是没有的</span></span><br><span class="line">      <span class="keyword">if</span> (sharedInstance != <span class="keyword">null</span> &amp;&amp; args == <span class="keyword">null</span>) &#123;</span><br><span class="line">         <span class="keyword">if</span> (logger.isTraceEnabled()) &#123;</span><br><span class="line">            <span class="keyword">if</span> (isSingletonCurrentlyInCreation(beanName)) &#123;</span><br><span class="line">               logger.trace(<span class="string">&quot;Returning eagerly cached instance of singleton bean &#x27;&quot;</span> + beanName +</span><br><span class="line">                     <span class="string">&quot;&#x27; that is not fully initialized yet - a consequence of a circular reference&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> &#123;</span><br><span class="line">               logger.trace(<span class="string">&quot;Returning cached instance of singleton bean &#x27;&quot;</span> + beanName + <span class="string">&quot;&#x27;&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">         &#125;</span><br><span class="line">         beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, <span class="keyword">null</span>);</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">else</span> &#123; <span class="comment">//默认第一次获取组件都会进入else环节</span></span><br><span class="line">         <span class="comment">// Fail if we&#x27;re already creating this bean instance:</span></span><br><span class="line">         <span class="comment">// We&#x27;re assumably within a circular reference.</span></span><br><span class="line">         <span class="keyword">if</span> (isPrototypeCurrentlyInCreation(beanName)) &#123;</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> BeanCurrentlyInCreationException(beanName);</span><br><span class="line">         &#125;</span><br><span class="line"></span><br><span class="line">         <span class="comment">// 拿到整个beanFactory的父工厂；看父工厂没有，从父工厂先尝试获取组件； Check if bean definition exists in this factory.</span></span><br><span class="line">         BeanFactory parentBeanFactory = getParentBeanFactory();</span><br><span class="line">         <span class="keyword">if</span> (parentBeanFactory != <span class="keyword">null</span> &amp;&amp; !containsBeanDefinition(beanName)) &#123; <span class="comment">//以下开始从父工厂获取组件</span></span><br><span class="line">            <span class="comment">// Not found -&gt; check parent.</span></span><br><span class="line">           <span class="comment">// ...</span></span><br><span class="line">         &#125;</span><br><span class="line"></span><br><span class="line">         <span class="keyword">if</span> (!typeCheckOnly) &#123;</span><br><span class="line">            markBeanAsCreated(beanName); <span class="comment">//标记当前beanName的bean已经被创建</span></span><br><span class="line">         &#125;</span><br><span class="line"></span><br><span class="line">         StartupStep beanCreation = <span class="keyword">this</span>.applicationStartup.start(<span class="string">&quot;spring.beans.instantiate&quot;</span>)</span><br><span class="line">               .tag(<span class="string">&quot;beanName&quot;</span>, name);</span><br><span class="line">         <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="keyword">if</span> (requiredType != <span class="keyword">null</span>) &#123;</span><br><span class="line">               beanCreation.tag(<span class="string">&quot;beanType&quot;</span>, requiredType::toString);</span><br><span class="line">            &#125;</span><br><span class="line">            RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);</span><br><span class="line">            checkMergedBeanDefinition(mbd, beanName, args);</span><br><span class="line"></span><br><span class="line">            <span class="comment">// Guarantee initialization of beans that the current bean depends on.</span></span><br><span class="line">            String[] dependsOn = mbd.getDependsOn();</span><br><span class="line">            <span class="keyword">if</span> (dependsOn != <span class="keyword">null</span>) &#123;</span><br><span class="line">               <span class="keyword">for</span> (String dep : dependsOn) &#123; <span class="comment">//看当前Bean有没有依赖其他Bean</span></span><br><span class="line">                  <span class="keyword">if</span> (isDependent(beanName, dep)) &#123;</span><br><span class="line">                     <span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(mbd.getResourceDescription(), beanName,</span><br><span class="line">                           <span class="string">&quot;Circular depends-on relationship between &#x27;&quot;</span> + beanName + <span class="string">&quot;&#x27; and &#x27;&quot;</span> + dep + <span class="string">&quot;&#x27;&quot;</span>);</span><br><span class="line">                  &#125;</span><br><span class="line">                  registerDependentBean(dep, beanName);</span><br><span class="line">                  <span class="keyword">try</span> &#123;</span><br><span class="line">                     getBean(dep); <span class="comment">//依赖了其他bean，就先获取其他的哪些bean</span></span><br><span class="line">                  &#125;</span><br><span class="line">                  <span class="keyword">catch</span> (NoSuchBeanDefinitionException ex) &#123;</span><br><span class="line">                     <span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(mbd.getResourceDescription(), beanName,</span><br><span class="line">                           <span class="string">&quot;&#x27;&quot;</span> + beanName + <span class="string">&quot;&#x27; depends on missing bean &#x27;&quot;</span> + dep + <span class="string">&quot;&#x27;&quot;</span>, ex);</span><br><span class="line">                  &#125;</span><br><span class="line">               &#125;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="comment">// 创建bean的实例；Create bean instance.</span></span><br><span class="line">            <span class="keyword">if</span> (mbd.isSingleton()) &#123;</span><br><span class="line">               sharedInstance = getSingleton(beanName, () -&gt; &#123;</span><br><span class="line">                  <span class="keyword">try</span> &#123;</span><br><span class="line">                     <span class="keyword">return</span> createBean(beanName, mbd, args);  <span class="comment">//创建bean对象的实例</span></span><br><span class="line">                  &#125;</span><br><span class="line">                  <span class="keyword">catch</span> (BeansException ex) &#123;</span><br><span class="line">                     <span class="comment">// Explicitly remove instance from singleton cache: It might have been put there</span></span><br><span class="line">                     <span class="comment">// eagerly by the creation process, to allow for circular reference resolution.</span></span><br><span class="line">                     <span class="comment">// Also remove any beans that received a temporary reference to the bean.</span></span><br><span class="line">                     destroySingleton(beanName);</span><br><span class="line">                     <span class="keyword">throw</span> ex;</span><br><span class="line">                  &#125;</span><br><span class="line">               &#125;); <span class="comment">//看当前bean是否是FactoryBean</span></span><br><span class="line">               beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">if</span> (mbd.isPrototype()) &#123;</span><br><span class="line">		<span class="comment">// ...</span></span><br><span class="line">		&#125;</span><br><span class="line">            <span class="keyword">else</span>&#123;&#125;</span><br><span class="line">       <span class="comment">// ...</span></span><br><span class="line">      <span class="comment">//转Object为Bean的T类型</span></span><br><span class="line">      <span class="keyword">return</span> adaptBeanInstance(name, beanInstance, requiredType);</span><br><span class="line">   &#125;</span><br><span class="line"></span><br><span class="line">      </span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">markBeanAsCreated</span><span class="params">(String beanName)</span> </span>&#123;</span><br><span class="line">	<span class="keyword">if</span> (!<span class="keyword">this</span>.alreadyCreated.contains(beanName)) &#123;</span><br><span class="line">		<span class="keyword">synchronized</span> (<span class="keyword">this</span>.mergedBeanDefinitions) &#123;</span><br><span class="line">			<span class="keyword">if</span> (!<span class="keyword">this</span>.alreadyCreated.contains(beanName)) &#123;</span><br><span class="line">				<span class="comment">// Let the bean definition get re-merged now that we&#x27;re actually creating</span></span><br><span class="line">				<span class="comment">// the bean... just in case some of its metadata changed in the meantime.</span></span><br><span class="line">				clearMergedBeanDefinition(beanName);</span><br><span class="line">				<span class="keyword">this</span>.alreadyCreated.add(beanName);</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line">      </span><br><span class="line">   <span class="comment">// 已经创建了的Bean名字池。Spring内部有很多这样记录Bean状态的集合（池子）</span></span><br><span class="line">   <span class="comment">/** Names of beans that have already been created at least once. */</span></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">final</span> Set&lt;String&gt; alreadyCreated = Collections.newSetFromMap(<span class="keyword">new</span> ConcurrentHashMap&lt;&gt;(<span class="number">256</span>));</span><br></pre></td></tr></table></figure>

<h4 id="DefaultSingletonBeanRegistry"><a href="#DefaultSingletonBeanRegistry" class="headerlink" title="DefaultSingletonBeanRegistry"></a>DefaultSingletonBeanRegistry</h4><blockquote>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">&#x2F;&#x2F; 先检查单实例bean的缓存 Eagerly check singleton cache for manually registered singletons.</span><br><span class="line">   Object sharedInstance &#x3D; getSingleton(beanName); &#x2F;&#x2F;检查缓存中有没有，如果是第一次获取肯定是没有的</span><br></pre></td></tr></table></figure>

<p>接上面</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">   <span class="meta">@Override</span></span><br><span class="line">   <span class="meta">@Nullable</span></span><br><span class="line">   <span class="function"><span class="keyword">public</span> Object <span class="title">getSingleton</span><span class="params">(String beanName)</span> </span>&#123;</span><br><span class="line">      <span class="keyword">return</span> getSingleton(beanName, <span class="keyword">true</span>);</span><br><span class="line">   &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//下面的代码是解决循环依赖的核心，后面细讲</span></span><br><span class="line"><span class="meta">@Nullable</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> Object <span class="title">getSingleton</span><span class="params">(String beanName, <span class="keyword">boolean</span> allowEarlyReference)</span> </span>&#123;</span><br><span class="line">	<span class="comment">//先检查单例缓存池，获取当前对象  Quick check for existing instance without full singleton lock</span></span><br><span class="line">	Object singletonObject = <span class="keyword">this</span>.singletonObjects.get(beanName); <span class="comment">//一级缓存</span></span><br><span class="line">	<span class="keyword">if</span> (singletonObject == <span class="keyword">null</span> &amp;&amp; isSingletonCurrentlyInCreation(beanName)) &#123; <span class="comment">//如果当前bean正在创建过程中，而且缓存中没有则继续</span></span><br><span class="line">		singletonObject = <span class="keyword">this</span>.earlySingletonObjects.get(beanName); <span class="comment">//二级</span></span><br><span class="line">		<span class="keyword">if</span> (singletonObject == <span class="keyword">null</span> &amp;&amp; allowEarlyReference) &#123;</span><br><span class="line">			<span class="keyword">synchronized</span> (<span class="keyword">this</span>.singletonObjects) &#123;</span><br><span class="line">				<span class="comment">// Consistent creation of early reference within full singleton lock</span></span><br><span class="line">				singletonObject = <span class="keyword">this</span>.singletonObjects.get(beanName);</span><br><span class="line">				<span class="keyword">if</span> (singletonObject == <span class="keyword">null</span>) &#123;</span><br><span class="line">					singletonObject = <span class="keyword">this</span>.earlySingletonObjects.get(beanName);</span><br><span class="line">					<span class="keyword">if</span> (singletonObject == <span class="keyword">null</span>) &#123;</span><br><span class="line">						ObjectFactory&lt;?&gt; singletonFactory = <span class="keyword">this</span>.singletonFactories.get(beanName); <span class="comment">//三级</span></span><br><span class="line">						<span class="keyword">if</span> (singletonFactory != <span class="keyword">null</span>) &#123;</span><br><span class="line">							singletonObject = singletonFactory.getObject();</span><br><span class="line">							<span class="keyword">this</span>.earlySingletonObjects.put(beanName, singletonObject);</span><br><span class="line">							<span class="keyword">this</span>.singletonFactories.remove(beanName);</span><br><span class="line">						&#125;</span><br><span class="line">					&#125;</span><br><span class="line">				&#125;</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">return</span> singletonObject;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/** 享元模式的单例。缓存所有单实例对象，单例对象池。ioc容器-单例池； Cache of singleton objects: bean name to bean instance. */</span></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">final</span> Map&lt;String, Object&gt; singletonObjects = <span class="keyword">new</span> ConcurrentHashMap&lt;&gt;(<span class="number">256</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 正在创建的组件的名字池</span></span><br><span class="line"><span class="comment">/** Names of beans that are currently in creation. */</span></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">final</span> Set&lt;String&gt; singletonsCurrentlyInCreation = Collections.newSetFromMap(<span class="keyword">new</span> ConcurrentHashMap&lt;&gt;(<span class="number">16</span>));</span><br><span class="line"></span><br></pre></td></tr></table></figure>





<h3 id="AbstractBeanFactory-doGetBean-创建Bean的核心代码"><a href="#AbstractBeanFactory-doGetBean-创建Bean的核心代码" class="headerlink" title="AbstractBeanFactory#doGetBean()创建Bean的核心代码"></a>AbstractBeanFactory#doGetBean()创建Bean的核心代码</h3><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">// 创建bean的实例；Create bean instance.</span></span><br><span class="line"><span class="keyword">if</span> (mbd.isSingleton()) &#123;</span><br><span class="line">   sharedInstance = getSingleton(beanName, () -&gt; &#123;</span><br><span class="line">      <span class="keyword">try</span> &#123;</span><br><span class="line">         <span class="keyword">return</span> createBean(beanName, mbd, args);  <span class="comment">//创建bean对象的实例</span></span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">catch</span> (BeansException ex) &#123;</span><br><span class="line">         <span class="comment">// Explicitly remove instance from singleton cache: It might have been put there</span></span><br><span class="line">         <span class="comment">// eagerly by the creation process, to allow for circular reference resolution.</span></span><br><span class="line">         <span class="comment">// Also remove any beans that received a temporary reference to the bean.</span></span><br><span class="line">         destroySingleton(beanName);</span><br><span class="line">         <span class="keyword">throw</span> ex;</span><br><span class="line">      &#125;</span><br><span class="line">   &#125;); <span class="comment">//看当前bean是否是FactoryBean</span></span><br><span class="line">   beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这里是创建Bean的核心，就是一个lamda表达式</p>
<h3 id="DefaultSingletonBeanRegistry-getSingleton"><a href="#DefaultSingletonBeanRegistry-getSingleton" class="headerlink" title="DefaultSingletonBeanRegistry#getSingleton()"></a>DefaultSingletonBeanRegistry#getSingleton()</h3><figure class="highlight java"><table><tr><td class="code"><pre><span class="line">   <span class="function"><span class="keyword">public</span> Object <span class="title">getSingleton</span><span class="params">(String beanName, ObjectFactory&lt;?&gt; singletonFactory)</span> </span>&#123;</span><br><span class="line">      Assert.notNull(beanName, <span class="string">&quot;Bean name must not be null&quot;</span>);</span><br><span class="line">      <span class="keyword">synchronized</span> (<span class="keyword">this</span>.singletonObjects) &#123;</span><br><span class="line">         Object singletonObject = <span class="keyword">this</span>.singletonObjects.get(beanName);</span><br><span class="line">         <span class="keyword">if</span> (singletonObject == <span class="keyword">null</span>) &#123; <span class="comment">//单实例池子里面没有当前对象（说明没有创建完成）</span></span><br><span class="line">            <span class="keyword">if</span> (<span class="keyword">this</span>.singletonsCurrentlyInDestruction) &#123;</span><br><span class="line">               <span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationNotAllowedException(beanName,</span><br><span class="line">                     <span class="string">&quot;Singleton bean creation not allowed while singletons of this factory are in destruction &quot;</span> +</span><br><span class="line">                     <span class="string">&quot;(Do not request a bean from a BeanFactory in a destroy method implementation!)&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (logger.isDebugEnabled()) &#123;</span><br><span class="line">               logger.debug(<span class="string">&quot;Creating shared instance of singleton bean &#x27;&quot;</span> + beanName + <span class="string">&quot;&#x27;&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            beforeSingletonCreation(beanName); <span class="comment">//单实例创建之前</span></span><br><span class="line">            <span class="keyword">boolean</span> newSingleton = <span class="keyword">false</span>;</span><br><span class="line">            <span class="keyword">boolean</span> recordSuppressedExceptions = (<span class="keyword">this</span>.suppressedExceptions == <span class="keyword">null</span>);</span><br><span class="line">            <span class="keyword">if</span> (recordSuppressedExceptions) &#123;</span><br><span class="line">               <span class="keyword">this</span>.suppressedExceptions = <span class="keyword">new</span> LinkedHashSet&lt;&gt;();</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">try</span> &#123;           </span><br><span class="line">               <span class="comment">/*</span></span><br><span class="line"><span class="comment">               1.这里会调用lamda表达式的内容，真正创建对象，也就是调用creatbean，</span></span><br><span class="line"><span class="comment">               2.ObjectFactory类注释上写了这里类似于一个工厂Bean，所以这里写的和工厂bean一样的getObject()。我们</span></span><br><span class="line"><span class="comment">               在前面是这样讲的</span></span><br><span class="line"><span class="comment">               3.但实际上ObjectFactory就是一个@FunctionalInterface标注的函数式接口，你调用它唯一的getObject()，那么</span></span><br><span class="line"><span class="comment">               当然就会调用createbean了。（这里就涉及lamda表达式的知识了，不知道的建议自行补习）</span></span><br><span class="line"><span class="comment">               */</span></span><br><span class="line">               singletonObject = singletonFactory.getObject();</span><br><span class="line">               newSingleton = <span class="keyword">true</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">catch</span> (IllegalStateException ex) &#123;</span><br><span class="line">               <span class="comment">// Has the singleton object implicitly appeared in the meantime -&gt;</span></span><br><span class="line">               <span class="comment">// if yes, proceed with it since the exception indicates that state.</span></span><br><span class="line">               singletonObject = <span class="keyword">this</span>.singletonObjects.get(beanName);</span><br><span class="line">               <span class="keyword">if</span> (singletonObject == <span class="keyword">null</span>) &#123;</span><br><span class="line">                  <span class="keyword">throw</span> ex;</span><br><span class="line">               &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">catch</span> (BeanCreationException ex) &#123;</span><br><span class="line">               <span class="keyword">if</span> (recordSuppressedExceptions) &#123;</span><br><span class="line">                  <span class="keyword">for</span> (Exception suppressedException : <span class="keyword">this</span>.suppressedExceptions) &#123;</span><br><span class="line">                     ex.addRelatedCause(suppressedException);</span><br><span class="line">                  &#125;</span><br><span class="line">               &#125;</span><br><span class="line">               <span class="keyword">throw</span> ex;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">finally</span> &#123;</span><br><span class="line">               <span class="keyword">if</span> (recordSuppressedExceptions) &#123;</span><br><span class="line">                  <span class="keyword">this</span>.suppressedExceptions = <span class="keyword">null</span>;</span><br><span class="line">               &#125;</span><br><span class="line">               afterSingletonCreation(beanName);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (newSingleton) &#123;</span><br><span class="line">               addSingleton(beanName, singletonObject);</span><br><span class="line">            &#125;</span><br><span class="line">         &#125;</span><br><span class="line">         <span class="keyword">return</span> singletonObject;</span><br><span class="line">      &#125;</span><br><span class="line">   &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">beforeSingletonCreation</span><span class="params">(String beanName)</span> </span>&#123;</span><br><span class="line">       <span class="comment">// 创建之前判断将Bean加入singletonsCurrentlyInCreation这个set集合</span></span><br><span class="line">	<span class="keyword">if</span> (!<span class="keyword">this</span>.inCreationCheckExclusions.contains(beanName) &amp;&amp; !<span class="keyword">this</span>.singletonsCurrentlyInCreation.add(beanName)) &#123;</span><br><span class="line">		<span class="keyword">throw</span> <span class="keyword">new</span> BeanCurrentlyInCreationException(beanName);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">afterSingletonCreation</span><span class="params">(String beanName)</span> </span>&#123;</span><br><span class="line">	<span class="keyword">if</span> (!<span class="keyword">this</span>.inCreationCheckExclusions.contains(beanName) &amp;&amp; !<span class="keyword">this</span>.singletonsCurrentlyInCreation.remove(beanName)) &#123;</span><br><span class="line">		<span class="keyword">throw</span> <span class="keyword">new</span> IllegalStateException(<span class="string">&quot;Singleton &#x27;&quot;</span> + beanName + <span class="string">&quot;&#x27; isn&#x27;t currently in creation&quot;</span>);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">addSingleton</span><span class="params">(String beanName, Object singletonObject)</span> </span>&#123;</span><br><span class="line">	<span class="keyword">synchronized</span> (<span class="keyword">this</span>.singletonObjects) &#123;</span><br><span class="line">		<span class="keyword">this</span>.singletonObjects.put(beanName, singletonObject);</span><br><span class="line">		<span class="keyword">this</span>.singletonFactories.remove(beanName);</span><br><span class="line">		<span class="keyword">this</span>.earlySingletonObjects.remove(beanName);</span><br><span class="line">		<span class="keyword">this</span>.registeredSingletons.add(beanName);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h3 id="AbstractAutowireCapableBeanFactory-createBean"><a href="#AbstractAutowireCapableBeanFactory-createBean" class="headerlink" title="AbstractAutowireCapableBeanFactory#createBean()"></a>AbstractAutowireCapableBeanFactory#createBean()</h3><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> Object <span class="title">createBean</span><span class="params">(String beanName, RootBeanDefinition mbd, <span class="meta">@Nullable</span> Object[] args)</span></span></span><br><span class="line"><span class="function">      <span class="keyword">throws</span> BeanCreationException </span>&#123;</span><br><span class="line"></span><br><span class="line">   <span class="keyword">if</span> (logger.isTraceEnabled()) &#123;</span><br><span class="line">      logger.trace(<span class="string">&quot;Creating instance of bean &#x27;&quot;</span> + beanName + <span class="string">&quot;&#x27;&quot;</span>);</span><br><span class="line">   &#125;</span><br><span class="line">   RootBeanDefinition mbdToUse = mbd;</span><br><span class="line"></span><br><span class="line">   <span class="comment">// Make sure bean class is actually resolved at this point, and</span></span><br><span class="line">   <span class="comment">// clone the bean definition in case of a dynamically resolved Class</span></span><br><span class="line">   <span class="comment">// which cannot be stored in the shared merged bean definition.</span></span><br><span class="line">   Class&lt;?&gt; resolvedClass = resolveBeanClass(mbd, beanName);</span><br><span class="line">   <span class="keyword">if</span> (resolvedClass != <span class="keyword">null</span> &amp;&amp; !mbd.hasBeanClass() &amp;&amp; mbd.getBeanClassName() != <span class="keyword">null</span>) &#123;</span><br><span class="line">      mbdToUse = <span class="keyword">new</span> RootBeanDefinition(mbd);</span><br><span class="line">      mbdToUse.setBeanClass(resolvedClass);</span><br><span class="line">   &#125;</span><br><span class="line"></span><br><span class="line">   <span class="comment">// Prepare method overrides.</span></span><br><span class="line">   <span class="keyword">try</span> &#123;</span><br><span class="line">      mbdToUse.prepareMethodOverrides();</span><br><span class="line">   &#125;</span><br><span class="line">   <span class="keyword">catch</span> (BeanDefinitionValidationException ex) &#123;</span><br><span class="line">      <span class="keyword">throw</span> <span class="keyword">new</span> BeanDefinitionStoreException(mbdToUse.getResourceDescription(),</span><br><span class="line">            beanName, <span class="string">&quot;Validation of method overrides failed&quot;</span>, ex);</span><br><span class="line">   &#125;</span><br><span class="line"></span><br><span class="line">   <span class="keyword">try</span> &#123;</span><br><span class="line">      <span class="comment">// 提前给我们一个机会，去返回组件的代理对象。 Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.</span></span><br><span class="line">      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);</span><br><span class="line">      <span class="keyword">if</span> (bean != <span class="keyword">null</span>) &#123;</span><br><span class="line">         <span class="keyword">return</span> bean;</span><br><span class="line">      &#125;</span><br><span class="line">   &#125;</span><br><span class="line">   <span class="keyword">catch</span> (Throwable ex) &#123;</span><br><span class="line">      <span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(mbdToUse.getResourceDescription(), beanName,</span><br><span class="line">            <span class="string">&quot;BeanPostProcessor before instantiation of bean failed&quot;</span>, ex);</span><br><span class="line">   &#125;</span><br><span class="line"></span><br><span class="line">   <span class="keyword">try</span> &#123; <span class="comment">//Spring真正自己创建对象</span></span><br><span class="line">      Object beanInstance = doCreateBean(beanName, mbdToUse, args);  <span class="comment">//这里的代码在前面已经讲的很清楚了</span></span><br><span class="line">      <span class="keyword">if</span> (logger.isTraceEnabled()) &#123;</span><br><span class="line">         logger.trace(<span class="string">&quot;Finished creating instance of bean &#x27;&quot;</span> + beanName + <span class="string">&quot;&#x27;&quot;</span>);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">return</span> beanInstance;</span><br><span class="line">   &#125;</span><br><span class="line">   <span class="keyword">catch</span> (BeanCreationException | ImplicitlyAppearedSingletonException ex) &#123;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">throw</span> ex;</span><br><span class="line">   &#125;</span><br><span class="line">   <span class="keyword">catch</span> (Throwable ex) &#123;</span><br><span class="line">      <span class="keyword">throw</span> <span class="keyword">new</span> BeanCreationException(</span><br><span class="line">            mbdToUse.getResourceDescription(), beanName, <span class="string">&quot;Unexpected exception during bean creation&quot;</span>, ex);</span><br><span class="line">   &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<p>doCreateBean那里就是一堆后置处理器的干预了，前面讲过</p>
<blockquote>
<p>至此，创建Bean的流程就和前面讲的衔接上了。</p>
</blockquote>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="mailto:undefined">youthlql</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="https://imlql.cn/post/49f419ae.html">https://imlql.cn/post/49f419ae.html</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://imlql.cn" target="_blank">风祈的时光录</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/Spring%E6%BA%90%E7%A0%81/">Spring源码</a></div><div class="post_share"></div></div><div class="post-reward"><div class="reward-button"><i class="fas fa-qrcode"></i> 打赏</div><div class="reward-main"><ul class="reward-all"><li class="reward-item"><a href="https://npm.elemecdn.com/youthlql@1.0.8/blog/wechat.jpg" target="_blank"><img class="post-qr-code-img" src= "" data-lazy-src="https://npm.elemecdn.com/youthlql@1.0.8/blog/wechat.jpg" alt="微信"/></a><div class="post-qr-code-desc">微信</div></li><li class="reward-item"><a href="https://npm.elemecdn.com/youthlql@1.0.8/blog/alipay.jpg" target="_blank"><img class="post-qr-code-img" src= "" data-lazy-src="https://npm.elemecdn.com/youthlql@1.0.8/blog/alipay.jpg" alt="支付宝"/></a><div class="post-qr-code-desc">支付宝</div></li></ul></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/post/a1b8c236.html"><img class="prev-cover" src= "" data-lazy-src="https://npm.elemecdn.com/lql_static@latest/logo/spring.png" onerror="onerror=null;src='/img/404.jpg'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">Spring源码系列-第5章-容器刷新流程</div></div></a></div><div class="next-post pull-right"><a href="/post/66c146e7.html"><img class="next-cover" src= "" data-lazy-src="https://npm.elemecdn.com/lql_static@latest/logo/spring.png" onerror="onerror=null;src='/img/404.jpg'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">Spring源码系列-第3章-后置处理器和Bean生命周期</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/post/41fb8d9e.html" title="Spring源码系列-第2章-后置工厂处理器和Bean生命周期"><img class="cover" src= "" data-lazy-src="https://npm.elemecdn.com/lql_static@latest/logo/spring.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2021-12-21</div><div class="title">Spring源码系列-第2章-后置工厂处理器和Bean生命周期</div></div></a></div><div><a href="/post/fb3552e0.html" title="Spring源码系列-第7章-AOP的执行流程原理和监听器原理"><img class="cover" src= "" data-lazy-src="https://npm.elemecdn.com/lql_static@latest/logo/spring.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-04-17</div><div class="title">Spring源码系列-第7章-AOP的执行流程原理和监听器原理</div></div></a></div><div><a href="/post/c8dd1418.html" title="Spring源码系列-第8章-SpringMVC子容器和Spring父容器的启动原理"><img class="cover" src= "" data-lazy-src="https://npm.elemecdn.com/lql_static@latest/logo/spring.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-06-20</div><div class="title">Spring源码系列-第8章-SpringMVC子容器和Spring父容器的启动原理</div></div></a></div><div><a href="/post/6f2cef28.html" title="Spring源码系列-第9章-SpringMVC请求处理源码和HandlerMapping原理"><img class="cover" src= "" data-lazy-src="https://npm.elemecdn.com/lql_static@latest/logo/spring.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-06-21</div><div class="title">Spring源码系列-第9章-SpringMVC请求处理源码和HandlerMapping原理</div></div></a></div><div><a href="/post/4dfb096b.html" title="Spring源码系列-第11章-SpringMVC异常处理源码和@EnableWebMvc原理"><img class="cover" src= "" data-lazy-src="https://npm.elemecdn.com/lql_static@latest/logo/spring.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2023-01-05</div><div class="title">Spring源码系列-第11章-SpringMVC异常处理源码和@EnableWebMvc原理</div></div></a></div><div><a href="/post/e3da4d66.html" title="Spring源码系列-第12章-SpringBoot源码-自动配置原理和内嵌Tomcat启动原理"><img class="cover" src= "" data-lazy-src="https://npm.elemecdn.com/lql_static@latest/logo/spring.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2023-01-06</div><div class="title">Spring源码系列-第12章-SpringBoot源码-自动配置原理和内嵌Tomcat启动原理</div></div></a></div></div></div></div><div class="aside-content" id="aside-content"><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content is-expand"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#%E7%AC%AC4%E7%AB%A0-Bean%E5%88%9D%E5%A7%8B%E5%8C%96%E6%B5%81%E7%A8%8B"><span class="toc-text">第4章-Bean初始化流程</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%B5%81%E7%A8%8B%E5%9B%BE-bean%E5%88%9D%E5%A7%8B%E5%8C%96%E6%B5%81%E7%A8%8B"><span class="toc-text">流程图-bean初始化流程</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#AbstractApplicationContext-refresh"><span class="toc-text">AbstractApplicationContext#refresh()</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#AbstractApplicationContext-finishBeanFactoryInitialization"><span class="toc-text">AbstractApplicationContext#finishBeanFactoryInitialization()</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#DefaultListableBeanFactory-preInstantiateSingletons"><span class="toc-text">DefaultListableBeanFactory#preInstantiateSingletons()</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%B7%A5%E5%8E%82Bean%E7%9A%84%E5%88%9D%E5%A7%8B%E5%8C%96%E6%96%B9%E5%BC%8F"><span class="toc-text">工厂Bean的初始化方式</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#AbstractBeanFactory-isFactoryBean"><span class="toc-text">AbstractBeanFactory#isFactoryBean()</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%B5%8B%E8%AF%95%E7%B1%BB"><span class="toc-text">测试类</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Debug%E8%B0%83%E7%94%A8%E6%A0%88"><span class="toc-text">Debug调用栈</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#DefaultListableBeanFactory-resolveBean"><span class="toc-text">DefaultListableBeanFactory#resolveBean()</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#DefaultListableBeanFactory-doGetBeanNamesForType"><span class="toc-text">DefaultListableBeanFactory#doGetBeanNamesForType()</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#BeanFactory"><span class="toc-text">BeanFactory</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Bean%E5%88%9B%E5%BB%BA%E7%9A%84%E5%89%8D%E6%9C%9F"><span class="toc-text">Bean创建的前期</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%B5%8B%E8%AF%95%E7%B1%BB-1"><span class="toc-text">测试类</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Debug%E8%B0%83%E7%94%A8%E6%A0%88-1"><span class="toc-text">Debug调用栈</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#AbstractBeanFactory-doGetBean"><span class="toc-text">AbstractBeanFactory#doGetBean()</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#DefaultSingletonBeanRegistry"><span class="toc-text">DefaultSingletonBeanRegistry</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#AbstractBeanFactory-doGetBean-%E5%88%9B%E5%BB%BABean%E7%9A%84%E6%A0%B8%E5%BF%83%E4%BB%A3%E7%A0%81"><span class="toc-text">AbstractBeanFactory#doGetBean()创建Bean的核心代码</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#DefaultSingletonBeanRegistry-getSingleton"><span class="toc-text">DefaultSingletonBeanRegistry#getSingleton()</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#AbstractAutowireCapableBeanFactory-createBean"><span class="toc-text">AbstractAutowireCapableBeanFactory#createBean()</span></a></li></ol></li></ol></li></ol></div></div></div></div></main><footer id="footer"><div id="footer-wrap"><div class="copyright">&copy;2020 - 2023 By youthlql</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div><div class="footer_custom_text"><a href="https://www.upyun.com/?utm_source=lianmeng&utm_medium=referral" target="_blank" rel="noopener" class="one-pan-link-mark"><img style="position:relative;top:-3px; " src= "" data-lazy-src="https://npm.elemecdn.com/lql_static@latest/upyun/logo.png" align="absmiddle" width="60px" height="30px"></a><a target="_blank" rel="noopener" href="https://beian.miit.gov.cn"><img class="icp-icon" src= "" data-lazy-src="https://npm.elemecdn.com/lql_static@latest/logo/icp.png"><span>鄂ICP备19028890号</span></a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="translateLink" type="button" title="简繁转换">简</button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">本地搜索</span><span id="loading-status"></span><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="is-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i><span>  数据库加载中</span></div><div class="search-wrap"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div><hr/><div id="local-search-results"></div></div></div><div id="search-mask"></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="/js/tw_cn.js"></script><script src="https://npm.elemecdn.com/@fancyapps/ui/dist/fancybox.umd.js"></script><script src="https://npm.elemecdn.com/instant.page/instantpage.js" type="module"></script><script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload/dist/lazyload.iife.min.js"></script><script src="/js/search/local-search.js"></script><div class="js-pjax"></div><script defer src="https://npm.elemecdn.com/jquery@latest/dist/jquery.min.js"></script></div></body></html>